package server

import (
	"log"
	"net"
	"crypto/tls"
	"grpc/helloworldgrpc/pkg/utils"
	"net/http"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"golang.org/x/net/context"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	pb "grpc/helloworldgrpc/proto"
)

var (
	ServerPort  string
	CertName    string
	CertPemPath string
	CertKeyPath string
	EndPoint    string
)

func Server() (err error) {

	EndPoint = ":" + ServerPort
	conn, err := net.Listen("tcp", EndPoint)
	if err != nil {
		log.Printf("Tcp Listen err:%v\n", err)
	}

	tlsConfig := utils.GetTLSConfig(CertPemPath, CertKeyPath)
	srv := createInternalServer(conn, tlsConfig)

	log.Printf("grpc and https listen on :%s\n", ServerPort)
	if err = srv.Serve(tls.NewListener(conn, tlsConfig)); err != nil {
		log.Printf("ListenAndServer :%v\n", err)
	}

	log.Println(ServerPort)
	log.Println(CertName)
	log.Println(CertPemPath)
	log.Println(CertKeyPath)

	return err
}
func createInternalServer(conn net.Listener, tlsConfig *tls.Config) (*http.Server) {

	var opts [] grpc.ServerOption

	//grpc server
	creds, err := credentials.NewServerTLSFromFile(CertPemPath, CertKeyPath)

	if err != nil {
		log.Printf("failed to create server tls credentials %v", err)
	}

	opts = append(opts, grpc.Creds(creds))
	grpcServer := grpc.NewServer(opts...)

	//register grep pb
	pb.RegisterHelloWorldServer(grpcServer, NewHelloService())
	//gw server
	ctx := context.Background()
	dcreds, err := credentials.NewClientTLSFromFile(CertPemPath, CertName)

	if err != nil {
		log.Printf("failed to creat client tls credentials %v", err)
	}

	dopts := []grpc.DialOption{grpc.WithTransportCredentials(dcreds)}
	gwmux := runtime.NewServeMux()

	//register grpc-gateway pb

	if err := pb.RegisterHelloWorldHandlerFromEndpoint(ctx, gwmux, EndPoint, dopts); err != nil {
		log.Printf("failed to register gw server :%v\n", err)
	}

	//http服务
	mux := http.NewServeMux()
	mux.Handle("/", gwmux)

	return &http.Server{
		Addr:      EndPoint,
		Handler:   utils.GrpcHandlerFunc(grpcServer, mux),
		TLSConfig: tlsConfig,
	}
}
